package com.rightsidetech.system.service.impl;

import com.alibaba.dubbo.rpc.RpcContext;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.utils.DateUtil;
import com.rightsidetech.commom.utils.StringUtil;
import com.rightsidetech.system.dtos.request.LoginAdminReq;
import com.rightsidetech.system.dtos.request.UpdatePasswordReq;
import com.rightsidetech.system.dtos.response.LoginResp;
import com.rightsidetech.system.entity.SysCompanyArea;
import com.rightsidetech.system.entity.SysUserLoginHistory;
import com.rightsidetech.system.entity.SysUserLoginInfo;
import com.rightsidetech.system.mapper.SysCompanyAreaMapper;
import com.rightsidetech.system.mapper.SysUserLoginHistoryMapper;
import com.rightsidetech.system.mapper.SysUserLoginInfoMapper;
import com.rightsidetech.system.service.SysLoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @Author: yhr
 * @Date: 2021-10-21 16:23
 */
@Slf4j
@Service("sysLoginServiceImpl")
public class SysLoginServiceImpl implements SysLoginService {
    @Resource
    private SysUserLoginInfoMapper sysUserLoginInfoMapper;

    @Resource
    private SysUserLoginHistoryMapper sysUserLoginHistoryMapper;

    @Resource
    private SysCompanyAreaMapper sysCompanyAreaMapper;

    @Override
    public ResponseData<LoginResp> login(LoginAdminReq loginReq,String ip) {
        SysUserLoginHistory sysUserLoginHistory = null;
        SysUserLoginInfo sysUserLoginInfo = null;
        try {
            sysUserLoginInfo = sysUserLoginInfoMapper.selectByLoginName(loginReq.getLoginName());
            //获取此次登录输入密码的md5值
            if (StringUtil.isNullorEmpty(sysUserLoginInfo)){
                return ResponseData.fail("未找到此账户，请确认是否正确");
            }
            if (sysUserLoginInfo.getStatus() == -1){
                return ResponseData.fail("此账号已被禁用，无法登录");
            }
            //大区关闭营业 限制登录
            SysCompanyArea sysCompanyArea = sysCompanyAreaMapper.selectByPrimaryKey(sysUserLoginInfo.getSysCompanyAreaId());
            if (!ObjectUtils.isEmpty(sysCompanyArea) && sysCompanyArea.getStatus() == -1){
                return ResponseData.fail("大区已停止营业，无法登录");
            }


            String md5DigestAsHex = StringUtils.isEmpty(loginReq.getPassword()) ? null : DigestUtils.md5DigestAsHex((loginReq.getPassword() + sysUserLoginInfo.getSalt()).getBytes());
            if (!md5DigestAsHex.equals(sysUserLoginInfo.getPassword())) {
                sysUserLoginHistory = historyParams((byte) -1);
                sysUserLoginHistory.setLoginInfoId(sysUserLoginInfo.getId());
                sysUserLoginHistory.setLoginIp(ip);
                sysUserLoginHistoryMapper.insert(sysUserLoginHistory);
                return ResponseData.fail(CodeIdEnum.UserNameOrPwdError);
            }
            String token = UUID.randomUUID().toString().replace("-", "");

            //更新loginInfo的token
            sysUserLoginInfoMapper.updateToken(sysUserLoginInfo.getId(),token);

            LoginResp loginResponse = sysUserLoginInfoMapper.selectLoginResDate(token);
            if (StringUtils.isEmpty(loginResponse)){
                return ResponseData.fail("用户数据存在隐患，无法登录");
            }

            //更新history
            SysUserLoginHistory historyDate = historyParams((byte) 0);
            historyDate.setLoginInfoId(sysUserLoginInfo.getId());
            historyDate.setLoginIp(ip);
            sysUserLoginHistoryMapper.insert(historyDate);

            if(!ObjectUtils.isEmpty(sysCompanyArea)){
                loginResponse.setAreaId(sysCompanyArea.getId());
            }

            return ResponseData.success(loginResponse);
        } catch (Exception e) {
            log.info("登录错误：调用方法：login",e);
            throw new RuntimeException("登录失败");
        }
    }
    private SysUserLoginHistory historyParams(Byte status) throws Exception {
        Date date = new Date();
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat fm = new SimpleDateFormat ("yyyy-MM-dd 02:00:00");
        SysUserLoginHistory historyDate = new SysUserLoginHistory();
        historyDate.setLoginTime(date);
        historyDate.setEffectiveTime(DateUtil.addDate(ft.parse(fm.format(date)), 14));
        //非常用地址ip登录
        historyDate.setStatus(status);
        historyDate.setLoginIp(RpcContext.getContext().getRemoteAddress().toString());
        return historyDate;
    }

    @Override
    public ResponseData logout(String token) {
        try {
            SysUserLoginInfo sysUserLoginInfo = sysUserLoginInfoMapper.selectLoginInfoByToken(token);
            if (StringUtil.isNullorEmpty(sysUserLoginInfo)){
                return ResponseData.fail(CodeIdEnum.NOLOGINACCOUNT);
            }
            //更新loginInfo表置空token
            sysUserLoginInfoMapper.updateLogout(token);

            SysUserLoginHistory historyData = sysUserLoginHistoryMapper.selectMaxIdByLoginInfoId(sysUserLoginInfo.getId());
            historyData.setLogoutTime(new Date());
            historyData.setEffectiveTime(historyData.getLogoutTime());
            sysUserLoginHistoryMapper.updateBatch(historyData);
            return ResponseData.success();
        }catch (Exception e){
            log.info("退出登录失败,失败方法：logout");
            return ResponseData.fail("退出登录失败");
        }
    }

    @Override
    public ResponseData updatePwd(UpdatePasswordReq req) {
        SysUserLoginInfo userLoginInfo = sysUserLoginInfoMapper.selectLoginInfoByToken(req.getToken());
        if (StringUtil.isNullorEmpty(userLoginInfo)){
            return ResponseData.fail("未找到此登录用户");
        }
        userLoginInfo.setSalt(String.valueOf(Math.random() * 900000 + 100000));
        userLoginInfo.setPassword(DigestUtils.md5DigestAsHex((req.getPassword() + userLoginInfo.getSalt()).getBytes()));
        sysUserLoginInfoMapper.updateByPrimaryKeySelective(userLoginInfo);
        sysUserLoginInfoMapper.updateLogout(req.getToken());
        return ResponseData.success();
    }

    @Override
    public SysUserLoginInfo selectById(String id) {
        return sysUserLoginInfoMapper.selectLoginInfoByToken(id);
    }
}
